package com.example.boot.service.admin;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.boot.bean.*;
import com.example.boot.bean.pojo.ReplyDetail;
import com.example.boot.bean.pojo.CountDetail;
import com.example.boot.mapper.*;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


@SuppressWarnings(value={"unchecked", "rawtypes"})
@Service
@Slf4j
public class AdminServiceImpl implements AdminService{
    @Autowired
    private ReplyInfoMapper replyInfoMapper;
    @Autowired
    private CountMapper countMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    PullMapper pullMapper;


    //左侧列表消费改造

    @Override
    public List queryList(int num) {
        ArrayList<CountDetail> list = new ArrayList<>();

        Set ids = redisTemplate.opsForZSet().reverseRange("Ids01", (num - 1) * 5, 5 * num - 1);

        //System.out.println(ids);

        if (ids.isEmpty()){
            list=null;
        }else {
            for (Object userId:ids) {
                CountDetail countDetail = new CountDetail();

                //存id值
                //System.out.println(userId);
                countDetail.setUserId(Integer.parseInt(userId.toString()));

                //存count

                Double count1 = redisTemplate.opsForZSet().score("count01", userId.toString());
                int count = (int) Math.round(count1);
                countDetail.setCount(count);

                //存入姓名

                String name = (String)redisTemplate.boundValueOps(userId.toString()).get();
                countDetail.setUser_name(name);

             list.add(countDetail);

           }
        }
        return list;
    }


    //客服拉取问题
    /*
     1.用户提出问题，根据用户有没有被绑定当前客服分两种情况对用户id信息存入redis（绑定了当前客服与未绑定任何客服）
     2.拉取问题时，如果绑定客服信息为5个，则将绑定信息全部拉取，不另外拉取新问题；如果不足五个，则拉取新问题补足五个，最后更新缓存和数据库状态
     */
    @Override
    public List pull(int aid){
        Lock lock = new ReentrantLock();
        ArrayList<CountDetail> list = new ArrayList<>();

            Set set = redisTemplate.opsForZSet().reverseRange(aid+"a", 0, -1);
            int size = set.size();
            int noAdmin = redisTemplate.opsForZSet().reverseRange("noAdmin2", 0, -1).size();
            Set<Integer> noAdmin1 ;
            if (noAdmin>=5-size) {
                 noAdmin1 = redisTemplate.opsForZSet().reverseRange("noAdmin2", 0, 4-size);
            }else {
                 noAdmin1 = redisTemplate.opsForZSet().reverseRange("noAdmin2", 0, -1);
            }

            if (set.size()==5){
                for (Object userId:set) {
                    CountDetail countDetail = new CountDetail();

                    //存id值

                    countDetail.setUserId(Integer.parseInt(userId.toString()));

                    //存count

                    Double count1 = redisTemplate.opsForZSet().score("count01", userId.toString());
                    int count = (int) Math.round(count1);
                    countDetail.setCount(count);

                    //存入姓名

                    String name = (String)redisTemplate.boundValueOps(userId.toString()).get();
                    countDetail.setUser_name(name);

                    list.add(countDetail);

                }
                ArrayList<Integer> sets = new ArrayList<>();
                if (null == set || set.size() == 0){
                    sets.add(-1);
                }else {
                    sets.addAll(set);
                }
                pullMapper.update(null, new UpdateWrapper<Pull>().lambda().in(Pull::getUserId, sets).set(Pull::getAdminId, aid));


            }else {
                if(set !=null && !set .equals("")) {
                    for (Object userId : set){
                        System.out.println(userId);
                        CountDetail countDetail = new CountDetail();

                        //存id值

                        countDetail.setUserId(Integer.parseInt((String) userId));
                        //存count

                        Double count1 = redisTemplate.opsForZSet().score("count01", userId.toString());
                        int count = (int) Math.round(count1);
                        countDetail.setCount(count);

                        //存入姓名

                        String name = (String) redisTemplate.boundValueOps(userId.toString()).get();
                        countDetail.setUser_name(name);

                        list.add(countDetail);

                    }
                }
                ArrayList<Integer> sets = new ArrayList<>();
                if (null == set || set.size() == 0) {
                    sets.add(-1);
                } else {
                    sets.addAll(set);
                }
                sets.addAll(set);
                pullMapper.update(null, new UpdateWrapper<Pull>().lambda().in(Pull::getUserId, sets).set(Pull::getAdminId, aid));
                if(noAdmin1 !=null && !noAdmin1 .equals("")) {
                    for (Object userId : noAdmin1) {
                        CountDetail countDetail = new CountDetail();
                        System.out.println(userId);
                        //存id值

                        countDetail.setUserId(Integer.parseInt(userId.toString()));

                        //存count

                        Double count1 = redisTemplate.opsForZSet().score("count01", userId.toString());
                        int count = (int) Math.round(count1);
                        countDetail.setCount(count);

                        //存入姓名

                        String name = (String) redisTemplate.boundValueOps(userId.toString()).get();
                        countDetail.setUser_name(name);

                        list.add(countDetail);
                    }
                }
                ArrayList<Integer> sets1 = new ArrayList<>();
                if (noAdmin1.isEmpty()){
                    //sets1.add(-1);
                }else {
                    sets1.addAll(noAdmin1);
                pullMapper.update(null, new UpdateWrapper<Pull>().lambda().in(Pull::getUserId, sets1).set(Pull::getAdminId, aid));
                }
                //拉取问题加锁
                lock.lock();
                try {
                for (int i = 0; i < sets1.size(); i++) {
                    //System.out.println(sets1.get(i));
                     redisTemplate.opsForZSet().remove("noAdmin2",String.valueOf(sets1.get(i)));
                    redisTemplate.opsForZSet().add(aid+"a",String.valueOf(sets1.get(i)),System.currentTimeMillis());
                }
                }catch (NumberFormatException e){
                    e.printStackTrace();
                }finally {
                lock.unlock();
                }
            }


        return list;
    }


    //右侧列表
    @Override
    public List queryList2(int uid, Integer pageNum) {
        Page<ReplyInfo> page = new Page<>(pageNum,5);

        //根据user_id得到问题集合page对象

        QueryWrapper<ReplyInfo> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(ReplyInfo::getUserId,uid)
        .select().orderByDesc(ReplyInfo::getId);
        IPage<ReplyInfo> iPage = replyInfoMapper.selectPage(page, wrapper);

        //遍历page对象，将所需数据存入新建列表对象

        List<ReplyInfo> records = iPage.getRecords();
        List<ReplyDetail> list = new ArrayList<>();
        for (ReplyInfo replyInfo:records) {
            ReplyDetail replyDetail = new ReplyDetail();
            String type = Type.type(replyInfo.getType());
            replyDetail.setTypes(type);
            replyDetail.setQuestion(replyInfo.getQuestion());
            replyDetail.setUserId(replyInfo.getUserId());
            replyDetail.setUserName(replyInfo.getUserName());
            replyDetail.setQuestionDate(replyInfo.getQuestionDate());

            // 是否有联系方式展示不同

            if (replyInfo.getContact()!=null){
                replyDetail.setContact("已填联系方式:"+replyInfo.getContact());
            }
            list.add(replyDetail);
        }
        return list;
    }

    //回答问题
    @Override
    public void alter(int id,String answer,int id1) {
        ReplyInfo info = replyInfoMapper.selectById(id);
        int userId = info.getUserId();
        int type = info.getType();

        //回复更新问题表并记录客服id

        UpdateWrapper<ReplyInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(ReplyInfo::getId,id);
        ReplyInfo replyInfo = new ReplyInfo();
        replyInfo.setAnswer(answer);
        replyInfo.setStatus(1);
        replyInfo.setAnswerDate(new Date());
        replyInfo.setUserId(userId);
        replyInfo.setType(type);
        replyInfoMapper.update(replyInfo,updateWrapper);
        redisTemplate.opsForZSet().incrementScore("count01",String.valueOf(userId),-1);

        //根据用户id得到该用户回复前count值

        QueryWrapper<Count> wrapper1 = new QueryWrapper<>();
        wrapper1.lambda().eq(Count::getId,userId);
        Count count1 = countMapper.selectOne(wrapper1);

        //回复后更新count值

        UpdateWrapper<Count> wrapper = new UpdateWrapper<>();
        wrapper.lambda().eq(Count::getId,userId);
        Count count = new Count();
        count.setCount(count1.getCount()-1);
        count.setId(userId);
        countMapper.update(count,wrapper);

        //更新pull
        log.info("此用户未回复count值为"+(count1.getCount()-1));
        if (count1.getCount()-1==0){
            pullMapper.update(null,new UpdateWrapper<Pull>().lambda().eq(Pull::getUserId,userId).set(Pull::getStatus,1));
            redisTemplate.opsForZSet().remove(userId+"a",String.valueOf(userId));
        }


    }

    //关闭问题列表
    public StringBuffer close(String adminName,int id,int aid){
        ReplyInfo info = replyInfoMapper.selectById(id);
        int userId = info.getUserId();
        int type = info.getType();

        //记录客服id

        UpdateWrapper<ReplyInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(ReplyInfo::getId,id);
        ReplyInfo replyInfo = new ReplyInfo();
        replyInfo.setStatus(1);
        replyInfo.setAnswerDate(new Date());
        replyInfo.setUserId(userId);
        replyInfo.setType(type);
        replyInfo.setStatus(2);
        replyInfoMapper.update(replyInfo,updateWrapper);
        redisTemplate.opsForZSet().incrementScore("count01",String.valueOf(userId),-1);

        //根据用户id得到该用户回复前count值

        QueryWrapper<Count> wrapper1 = new QueryWrapper<>();
        wrapper1.lambda().eq(Count::getId,userId);
        Count count1 = countMapper.selectOne(wrapper1);

        //回复后更新count值

        UpdateWrapper<Count> wrapper = new UpdateWrapper<>();
        wrapper.lambda().eq(Count::getId,userId);
        Count count = new Count();
        count.setCount(count1.getCount()-1);
        count.setId(userId);
        countMapper.update(count,wrapper);

        StringBuffer append1;
        append1 = new StringBuffer().append("客服").append(adminName).append("关闭了会话");
        return append1;
    }

    //客服登录
    @Autowired
    private AdminMapper adminMapper;

    public Admin adminLogin(Admin admin) {
        QueryWrapper<Admin> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Admin::getAdminName,admin.getAdminName());
        return adminMapper.selectOne(wrapper);
    }

    //新建自定义问题
    @Autowired
    QuestionMapper questionMapper;

    public void add(Question question,int id){
        question.setAdminId(id);
        Date date = new Date();
        question.setAdd_date(date);
        questionMapper.insert(question);
    }

    //自定义问题列表
    public List<StringBuffer> ListByOrder(int id){
        QueryWrapper<Question> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Question::getAdminId,id)
        .select().orderByDesc(Question::getId);
        List<Question> questions = questionMapper.selectList(wrapper);
        ArrayList<StringBuffer> list = new ArrayList<>();
        for (int i = 0; i < questions.size(); i++) {
            Question question = questions.get(i);
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append(i+1+"."+question.getAnswer());
            list.add(stringBuffer);
        }
        return list;
    }

    //删除自定义回复
    public void delete(int id){
        QueryWrapper<Question> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Question::getId,id);
        questionMapper.delete(wrapper);
    }

}
